Skip to content

src: add event loop based metrics into node#62935

Merged
nodejs-github-bot merged 9 commits into
nodejs:mainfrom
pabloerhard:pabloerhard/add-event-loop-metrics
Jun 24, 2026
Merged

src: add event loop based metrics into node#62935
nodejs-github-bot merged 9 commits into
nodejs:mainfrom
pabloerhard:pabloerhard/add-event-loop-metrics

Conversation

@pabloerhard

@pabloerhard pabloerhard commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Adds an opt in into monitorEventLoopDelay(), this option adds support for per iteration sampling using libuv hooks, while preserving the existing timer based approach.

When the new samplePerIteration option is set to true, monitorEventLoopDelay() samples directly from event loop iterations instead of using the interval timer. When samplePerIteration is omitted or false, the existing interval based implementation remains unchanged, including resolution handling and the older interval based trace counters.

Motivation
The interval based implementation has two limitations that the new option addresses:

  • Inaccurate measurements. Delay was approximated from a timer dispatch jitter (RecordDelta() between timer ticks) rather than measured from the loop itself. Samples had an implicit floor of resolution ms and could miss delays that didn't happen to coincide with a timer tick.
  • Wasteful wake ups. The timer forced the event loop to iterate every resolution ms just to record a sample, even when the application was otherwise idle and no one was reading the histogram.

This is an alternative implementation to the one in #62934

This PR directly addresses the following issue #56064

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Apr 24, 2026
Comment thread src/histogram.cc Outdated
Comment thread src/histogram.cc Outdated
@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from edb66ea to e7093c8 Compare April 28, 2026 20:12
@pabloerhard pabloerhard marked this pull request as ready for review April 29, 2026 18:38
@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from 6f5cdca to bc0a59c Compare April 30, 2026 17:55
@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.51852% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.64%. Comparing base (80e0f14) to head (27ead1e).
⚠️ Report is 109 commits behind head on main.

Files with missing lines Patch % Lines
src/histogram.cc 79.50% 11 Missing and 14 partials ⚠️
src/histogram.h 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62935      +/-   ##
==========================================
- Coverage   89.65%   89.64%   -0.02%     
==========================================
  Files         708      708              
  Lines      220413   220546     +133     
  Branches    42275    42290      +15     
==========================================
+ Hits       197607   197702      +95     
- Misses      14658    14675      +17     
- Partials     8148     8169      +21     
Files with missing lines Coverage Δ
lib/internal/perf/event_loop_delay.js 95.95% <100.00%> (+0.12%) ⬆️
src/node_perf.cc 86.61% <100.00%> (+0.22%) ⬆️
src/histogram.h 50.00% <0.00%> (-10.00%) ⬇️
src/histogram.cc 79.08% <79.50%> (+0.12%) ⬆️

... and 33 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from bc0a59c to 27ead1e Compare April 30, 2026 23:33
@BridgeAR BridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label May 11, 2026
@pabloerhard pabloerhard requested review from addaleax and bengl May 12, 2026 19:51
@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from 27ead1e to 3b21617 Compare May 19, 2026 21:21
Comment thread doc/api/perf_hooks.md
Comment thread doc/api/perf_hooks.md
Comment thread src/histogram.cc Outdated
Comment thread test/sequential/test-performance-eventloopdelay.js
@pabloerhard pabloerhard requested a review from BridgeAR June 11, 2026 09:05

@BridgeAR BridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty much LGTM, just left two nits. I would feel more comfortable with someone else reviewing it as well.

@addaleax @jasnell maybe?

Comment thread doc/api/perf_hooks.md Outdated
Comment thread src/histogram.cc Outdated
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 17, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from 71f121f to 88fce8d Compare June 17, 2026 16:56
@pabloerhard pabloerhard requested a review from BridgeAR June 17, 2026 20:18
@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from 50f8eab to 29b708d Compare June 18, 2026 13:32

@BridgeAR BridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, while I would still like to get another LG who works on CPP frequently

@BridgeAR BridgeAR requested review from Qard, jasnell and legendecas June 18, 2026 15:24
pabloerhard and others added 8 commits June 23, 2026 18:03
Add test coverage for the per iteration event loop delay histogram start
and stop callbacks

Use disitinct debug tracking keys for the event loop delay histogram
callbacks.
Use the super Close method instead of duplicating code
Added extra test to add coverage of the overall functionality of the new
ELD histogram.
Update docs to match the event loop delay sampling changes.
The C++ class `ELDHistogram` is the per-iteration sampling
implementation that sits next to `IntervalHistogram` (the
timer-based one). Its name collided with the JS exposed

`ELDHistogram` class that `monitorEventLoopDelay()` returns
regardless of sampling mode, making the layering confusing:
"ELDHistogram" was both the generic JS concept and the name of
one specific C++ backing.
align perf_hooks docs after renaming internal ELDHistogram to
IterationHistogram
Added shared templates for duplicated start/stop
logic in IntevalHistogram and IterationHistogram.
@pabloerhard pabloerhard force-pushed the pabloerhard/add-event-loop-metrics branch from 7666e61 to 3f20e89 Compare June 23, 2026 22:10
@BridgeAR BridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label Jun 24, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 24, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@bengl bengl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo discussion of semver level. That's non-blocking though, since this can land as major if desired.

@bengl bengl added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jun 24, 2026
@bengl

bengl commented Jun 24, 2026

Copy link
Copy Markdown
Member

Per discussion offline w/ @BridgeAR, yeah it's a docs-only change, so removing the label.

@bengl bengl removed the semver-major PRs that contain breaking changes and should be released in the next major version. label Jun 24, 2026
@BridgeAR BridgeAR added semver-minor PRs that contain new features and should be released in the next minor version. commit-queue Add this label to land a pull request using GitHub Actions. labels Jun 24, 2026
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels Jun 24, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator
Commit Queue failed
- Loading data for nodejs/node/pull/62935
✔  Done loading data for nodejs/node/pull/62935
----------------------------------- PR info ------------------------------------
Title      src: add event loop based metrics into node (#62935)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     pabloerhard:pabloerhard/add-event-loop-metrics -> nodejs:main
Labels     c++, semver-minor, needs-ci
Commits    9
 - perf_hooks: sample delay per event loop iteration
 - perf_hooks: test event loop delay fast api callbacks
 - perf_hooks: format cpp
 - perf_hooks: use super Close method
 - test: improve event loop delay sample-per-iteration coverage
 - doc: update perf_hooks histogram docs
 - perf_hooks: rename internal ELDHistogram to IterationHistogram
 - doc: align perf_hooks histogram class name with implementation
 - perf_hooks: deduplicate histogram Start/Stop via shared templates
Committers 1
 - Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
PR-URL: https://github.com/nodejs/node/pull/62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Fri, 24 Apr 2026 18:31:31 GMT
   ✔  Approvals: 3
   ✔  - Bryan English (@bengl): https://github.com/nodejs/node/pull/62935#pullrequestreview-4565608564
   ✔  - Ruben Bridgewater (@BridgeAR) (TSC): https://github.com/nodejs/node/pull/62935#pullrequestreview-4561486814
   ✔  - James M Snell (@jasnell) (TSC): https://github.com/nodejs/node/pull/62935#pullrequestreview-4565515487
   ✔  Last GitHub CI successful
   ℹ  Last Full PR CI on 2026-06-24T11:12:09Z: https://ci.nodejs.org/job/node-test-pull-request/74399/
- Querying data for job/node-test-pull-request/74399/
✔  Build data downloaded
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  No git cherry-pick in progress
   ✔  No git am in progress
   ✔  No git rebase in progress
--------------------------------------------------------------------------------
- Bringing origin/main up to date...
From https://github.com/nodejs/node
 * branch                  main       -> FETCH_HEAD
✔  origin/main is now up-to-date
- Downloading patch for 62935
From https://github.com/nodejs/node
 * branch                  refs/pull/62935/merge -> FETCH_HEAD
✔  Fetched commits as 6f11fe7d67c1..3f20e89304dc
--------------------------------------------------------------------------------
[main 1ae0f285c6] perf_hooks: sample delay per event loop iteration
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Fri Apr 24 14:28:07 2026 -0400
 7 files changed, 288 insertions(+), 13 deletions(-)
[main 6e4c7e5150] perf_hooks: test event loop delay fast api callbacks
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Thu Apr 30 13:54:56 2026 -0400
 2 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 test/parallel/test-perf-hooks-monitor-event-loop-delay-fast-calls.js
[main d46716593b] perf_hooks: format cpp
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Thu Apr 30 19:33:22 2026 -0400
 3 files changed, 30 insertions(+), 49 deletions(-)
[main 9aa569e8d4] perf_hooks: use super Close method
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Tue May 19 17:20:45 2026 -0400
 2 files changed, 2 insertions(+), 17 deletions(-)
[main b033f8fef1] test: improve event loop delay sample-per-iteration coverage
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Wed May 27 15:38:42 2026 -0400
 1 file changed, 83 insertions(+)
[main 81acec265c] doc: update perf_hooks histogram docs
 Author: pabloerhard <pabloerhard02@gmail.com>
 Date: Wed May 27 15:48:50 2026 -0400
 1 file changed, 20 insertions(+), 8 deletions(-)
[main 27fd9191f7] perf_hooks: rename internal ELDHistogram to IterationHistogram
 Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
 Date: Wed Jun 17 12:54:37 2026 -0400
 5 files changed, 47 insertions(+), 45 deletions(-)
[main 32b0132990] doc: align perf_hooks histogram class name with implementation
 Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
 Date: Wed Jun 17 12:55:39 2026 -0400
 1 file changed, 9 insertions(+), 13 deletions(-)
[main 8f7515eb61] perf_hooks: deduplicate histogram Start/Stop via shared templates
 Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
 Date: Wed Jun 17 13:43:59 2026 -0400
 4 files changed, 49 insertions(+), 31 deletions(-)
   ✔  Patches applied
There are 9 commits in the PR. Attempting autorebase.
(node:355) [DEP0190] DeprecationWarning: Passing args to a child process with shell option true can lead to security vulnerabilities, as the arguments are not escaped, only concatenated.
(Use `node --trace-deprecation ...` to show where the warning was created)
Rebasing (2/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: sample delay per event loop iteration

Add a samplePerIteration option to monitorEventLoopDelay that records
event loop delay from libuv event loop iterations instead of the timer
interval sampler. The default remains interval-based; existing uses of
monitorEventLoopDelay() keep behaving the same unless the
samplePerIteration option is passed through.

Signed-off-by: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 99e0587b63] perf_hooks: sample delay per event loop iteration
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Fri Apr 24 14:28:07 2026 -0400
7 files changed, 288 insertions(+), 13 deletions(-)
Rebasing (3/18)
Rebasing (4/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: test event loop delay fast api callbacks

Add test coverage for the per iteration event loop delay histogram start
and stop callbacks

Use disitinct debug tracking keys for the event loop delay histogram
callbacks.

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 04ff481a23] perf_hooks: test event loop delay fast api callbacks
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Thu Apr 30 13:54:56 2026 -0400
2 files changed, 28 insertions(+), 2 deletions(-)
create mode 100644 test/parallel/test-perf-hooks-monitor-event-loop-delay-fast-calls.js
Rebasing (5/18)
Rebasing (6/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: format cpp

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 4da679c175] perf_hooks: format cpp
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Thu Apr 30 19:33:22 2026 -0400
3 files changed, 30 insertions(+), 49 deletions(-)
Rebasing (7/18)
Rebasing (8/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: use super Close method

Use the super Close method instead of duplicating code

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD fee3435215] perf_hooks: use super Close method
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Tue May 19 17:20:45 2026 -0400
2 files changed, 2 insertions(+), 17 deletions(-)
Rebasing (9/18)
Rebasing (10/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
test: improve event loop delay sample-per-iteration coverage

Added extra test to add coverage of the overall functionality of the new
ELD histogram.

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD de2fd35a9b] test: improve event loop delay sample-per-iteration coverage
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Wed May 27 15:38:42 2026 -0400
1 file changed, 83 insertions(+)
Rebasing (11/18)
Rebasing (12/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
doc: update perf_hooks histogram docs

Update docs to match the event loop delay sampling changes.

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 3a5541879c] doc: update perf_hooks histogram docs
Author: pabloerhard <pabloerhard02@gmail.com>
Date: Wed May 27 15:48:50 2026 -0400
1 file changed, 20 insertions(+), 8 deletions(-)
Rebasing (13/18)
Rebasing (14/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: rename internal ELDHistogram to IterationHistogram

The C++ class ELDHistogram is the per-iteration sampling
implementation that sits next to IntervalHistogram (the
timer-based one). Its name collided with the JS exposed

ELDHistogram class that monitorEventLoopDelay() returns
regardless of sampling mode, making the layering confusing:
"ELDHistogram" was both the generic JS concept and the name of
one specific C++ backing.

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 69e6b6803a] perf_hooks: rename internal ELDHistogram to IterationHistogram
Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
Date: Wed Jun 17 12:54:37 2026 -0400
5 files changed, 47 insertions(+), 45 deletions(-)
Rebasing (15/18)
Rebasing (16/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
doc: align perf_hooks histogram class name with implementation

align perf_hooks docs after renaming internal ELDHistogram to
IterationHistogram

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD 01d5e37ecc] doc: align perf_hooks histogram class name with implementation
Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
Date: Wed Jun 17 12:55:39 2026 -0400
1 file changed, 9 insertions(+), 13 deletions(-)
Rebasing (17/18)
Rebasing (18/18)
Executing: git node land --amend --yes
--------------------------------- New Message ----------------------------------
perf_hooks: deduplicate histogram Start/Stop via shared templates

Added shared templates for duplicated start/stop
logic in IntevalHistogram and IterationHistogram.

PR-URL: #62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>

[detached HEAD ff43664599] perf_hooks: deduplicate histogram Start/Stop via shared templates
Author: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
Date: Wed Jun 17 13:43:59 2026 -0400
4 files changed, 49 insertions(+), 31 deletions(-)
Successfully rebased and updated refs/heads/main.

ℹ Add commit-queue-squash label to land the PR as one commit, or commit-queue-rebase to land as separate commits.

https://github.com/nodejs/node/actions/runs/28128367127

@BridgeAR BridgeAR added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. and removed commit-queue-failed An error occurred while landing this pull request using GitHub Actions. labels Jun 24, 2026
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 24, 2026
@nodejs-github-bot nodejs-github-bot merged commit c5635b8 into nodejs:main Jun 24, 2026
88 of 89 checks passed
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in c5635b8

luanmuniz pushed a commit to luanmuniz/node that referenced this pull request Jun 25, 2026
Add a samplePerIteration option to monitorEventLoopDelay that records
event loop delay from libuv event loop iterations instead of the timer
interval sampler. The default remains interval-based; existing uses of
monitorEventLoopDelay() keep behaving the same unless the
samplePerIteration option is passed through.

Signed-off-by: Pablo Erhard <pablo.erhardhernandez@datadoghq.com>
PR-URL: nodejs#62935
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants